#ifndef _FRAMEWORK_CANROUTE_H_
#define _FRAMEWORK_CANROUTE_H_

#include "DbcParser.h"
#include "UsbCan.h"
#include "Ican.h"
#include <vector>
#include <iostream>
#include <memory>
#include <map>
#include <thread>
#include <mutex>

class CanRoute
{
public:
    CanRoute();
    ~CanRoute();

    void init();
    bool start();
    void stop();

    void sendSignal(const uint16_t& msgId, const std::string& sigName, double value);
    int  getMsgIdBySigName(const char* sigName);

    bool isRouteRunning() const;
    bool getSigPhysicsData(const uint32_t& canId, const std::string& signalName, double& out);
    static std::unique_ptr<CanRoute>& getInstance();

private:
    void sendLoop();
    void updateRecvData(ZCAN_Receive_Data* input);


    DbcParser      itsDbcPaser;
    zlg::UsbCan    itsCan;

    std::thread             itsSendThread;
    std::atomic_bool        isRunning;
    std::mutex              itsMutex;
    std::mutex              itsRecvMutex;
    std::condition_variable itsCond;
    ZCAN_Receive_Data       itsRecvData[ICan::MAX_RECV_SIZE];

    std::map<uint32, DBCMessage*> itsSendPool;
    std::map<uint32, DBCMessage*> itsRecvPool;

    static std::unique_ptr<CanRoute> canRouteInstance;

    static constexpr const char* DBC_PATH = "./IC.dbc";
};

#endif
